#define _CRT_SECURE_NO_WARNINGS 1

#include"Heap.h"


void HPInit(HP* pc)
{
	assert(pc);
	pc->a = (HPDataPyde*)malloc(sizeof(HPDataPyde)*4);
	if (pc->a == NULL)
	{
		perror("malloc");
		return;
	}
	pc->sz = 0;
	pc->capacity = 4;
}

void HPDestroy(HP* pc)
{
	assert(pc);
	free(pc->a);
	pc->a = NULL;
	pc->sz = pc->capacity = 0;
}

void swap(HPDataPyde* a,HPDataPyde* b)
{
	HPDataPyde tmp = *a;
	*a = *b;
	*b = tmp;
}

void HPAdjustPush(HP* pc,int child)
{
	assert(pc);
	int father = (child - 1) / 2;
	while (child > 0)
	{
		if (pc->a[father] > pc->a[child])
		{
			swap(&pc->a[father], &pc->a[child]);
			child = father;
			father = (child - 1) / 2;
		}
		else
		{
			return;
		}
	}
}

void HPPush(HP* pc, HPDataPyde x)
{
	assert(pc);
	if (pc->sz == pc->capacity)
	{
		HPDataPyde* tmp = (HPDataPyde*)realloc(pc->a, sizeof(HPDataPyde) * pc->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc");
			return;
		}
		pc->a = tmp;
		pc->capacity *= 2;
	}  
	pc->a[pc->sz] = x;

	pc->sz++;

	HPAdjustPush(pc, pc->sz-1);
}

void HPAdjustdown(HP* pc, int father)
{
	assert(pc);

	HPDataPyde child = father * 2 + 1;
	while (child < pc->sz)
	{
		if (child+1 < pc->sz && pc->a[child] < pc->a[child + 1])
		{
			child++;
		}
		if (pc->a[father] > pc->a[child])
		{
			swap(&pc->a[father], &pc->a[child]);
			father = child;
			child = father * 2 + 1;
		}
		else
		{
			return;
		}
	}
}

void HPPop(HP* pc)
{
	assert(pc);
	swap(&pc->a[0],&pc->a[pc->sz-1]);

	pc->sz--;

	HPAdjustdown(pc, 0);
}

void HPPrint(HP* pc)
{
	assert(pc);
	for(int i = 0; i < pc->sz; i++)
	{
		printf("%d ", pc->a[i]);
	}
	printf("\n");
}
